#ifndef __CHANNEL_included
#define __CHANNEL_included

#include <exception>
#include <string>
#include <boost/shared_ptr.hpp>
#include <boost/exception/all.hpp>
#include <boost/asio.hpp>
#include "PackageReceiver.h"
#include "../engine/PackageFactory.h"

class CChannelException : public virtual std::exception, public virtual boost::exception {};
typedef boost::error_info<struct tag_channel_error, string> channel_error;

class CChannel {

protected :

	std::string mRemoteAddr;
	boost::shared_ptr<Engine::CRequestAllocator> mRequestAllocator;
	PackageReceiverRef mPackageReceiver;

public :

	CChannel();
	
	virtual void ScheduleReceive(PackageReceiverRef receiver) = 0;
	virtual void SetupLocal(int local_port) = 0;
	virtual void SetupRemote(std::string& remote_addr, int remote_port) = 0;
	virtual void Send(boost::shared_ptr<Engine::CPackage> p) = 0;
	virtual boost::shared_ptr<Engine::CPackage> ReceivePackage() = 0;
	virtual void GetLocalIPAddress(string& ip) = 0;
	virtual void GetRemoteIPAddress(string& ip) = 0;

	virtual void Close() {
		mPackageReceiver.reset();
	}
};

typedef boost::shared_ptr<CChannel> ChannelRef;

#endif //__CHANNEL_included